home *** CD-ROM | disk | FTP | other *** search
Text File | 1997-08-18 | 3.9 KB | 131 lines | [TEXT/R*ch] |
- (* Array2 -- as of 1995-09-12, 1997-03-12 *)
-
- (* Representation of an m * n array: an m-vector of n-arrays (rows),
- and the dimensions (m, n), m = number of rows, n = number of columns. *)
-
- (* The implementation below is pretty naive, using the Array and Vector
- operations and doing more bounds checks than strictly necessary. *)
-
- type 'a array2 = ('a Array.array Vector.vector * int * int) ref
-
- type region = { row : int, col : int, ht : int option, wd : int option}
-
- fun fromList [] = ref (Vector.fromList [], 0, 0)
- | fromList (xs1 :: xsr) =
- let val row1 = Array.fromList xs1
- val rowr = List.map Array.fromList xsr
- val cols = Array.length row1
- val vec =
- if List.all (fn r => Array.length r = cols) rowr then
- Vector.fromList (row1 :: rowr)
- else
- raise Size
- in
- ref (vec, Vector.length vec, cols)
- end
-
- fun array (m, n, x) =
- ref (Vector.tabulate(m, fn _ => Array.array(n, x)), m, n);
-
- fun tabulate (m, n, f) =
- ref (Vector.tabulate(m, fn i => Array.tabulate(n, fn j => f(i,j))), m, n);
-
- fun dimensions (ref (a,m,n)) = (m,n);
-
- fun height (ref (a,m,n)) = m;
-
- fun width (ref (a,m,n)) = n;
-
- fun sub(ref (a,m,n), i, j) = Array.sub(Vector.sub(a, i), j);
-
- fun update(ref (a,m,n), i, j, x) = Array.update(Vector.sub(a, i), j, x);
-
- fun row (ref (a, _, _), i) =
- Array.extract(Vector.sub(a, i), 0, NONE);
-
- fun column (ref (a, m, n), j) =
- if j<0 orelse j>=n then raise Subscript
- else Vector.tabulate(m, fn k => Array.sub(Vector.sub(a, k), j))
-
- fun app f (ref (a, _, _)) =
- Vector.app (Array.app f) a
-
- fun appi f (ref (a, _, _), { row, col, ht, wd }) =
- Vector.appi
- (fn (i, xs) => Array.appi (fn (j, x) => f(i, j, x)) (xs, col, wd))
- (a, row, ht)
-
- fun modify f (ref (a, _, _)) =
- Vector.app (Array.modify f) a
-
- fun modifyi f (ref (a, _, _), { row, col, ht, wd }) =
- Vector.appi
- (fn (i, xs) => Array.modifyi (fn (j, x) => f(i, j, x)) (xs, col, wd))
- (a, row, ht)
-
- datatype traversal = RowMajor | ColMajor
-
- fun fold RowMajor f b (ref (a, _, _)) =
- Vector.foldl (fn (xs, res) => Array.foldl f res xs) b a
- | fold ColMajor f b (ref (a, m, n)) =
- let fun rows j i b =
- if i >= m then b
- else rows j (i+1) (f(Array.sub(Vector.sub(a, i), j), b))
- fun cols j b =
- if j >= n then b
- else cols (j+1) (rows j 0 b)
- in cols 0 b end
-
- fun stop len i NONE =
- if i<0 orelse i>len then raise Subscript
- else len
- | stop len i (SOME n) =
- if i<0 orelse n<0 orelse i+n>len then raise Subscript
- else i+n;
-
- fun foldi RowMajor f b (ref (a, m, n), { row, col, ht, wd }) =
- Vector.foldli
- (fn (i, xs, res) =>
- Array.foldli (fn (j,x,res) => f(i,j,x,res)) res (xs,col,wd))
- b (a, row, ht)
- | foldi ColMajor f b (ref (a, m, n), reg as { row, col, ht, wd }) =
- let val stoprow = stop m row ht
- val stopcol = stop n col wd
- fun rows j i b =
- if i >= stoprow then b
- else rows j (i+1) (f(i, j, Array.sub(Vector.sub(a, i), j), b))
- fun cols j b =
- if j >= stopcol then b
- else cols (j+1) (rows j row b)
- in cols col b end
-
- fun copy { src = ref (sa, sm, sn), dst = ref (da, dm, dn),
- src_reg = { row = src_row, col = src_col, ht, wd },
- dst_row, dst_col } =
- let val stoprow = stop sm src_row ht
- fun bottomUp from_row to_row =
- if from_row < src_row then ()
- else
- (Array.copy { src = Vector.sub(sa, from_row),
- si = src_col, len = wd,
- dst = Vector.sub(da, to_row),
- di = dst_col };
- bottomUp (from_row-1) (to_row-1))
- fun topDown from_row to_row =
- if from_row >= stoprow then ()
- else
- (Array.copy { src = Vector.sub(sa, from_row),
- si = src_col, len = wd,
- dst = Vector.sub(da, to_row),
- di = dst_col };
- topDown (from_row+1) (to_row+1))
- in
- if src_row <= dst_row then (* top dst overlaps with bot src;
- copy bottom-up *)
- bottomUp (stoprow-1) (stoprow-1+dst_row-src_row)
- else (* bot dst overlaps with top src; copy top-down *)
- topDown src_row dst_row
- end
-
-
-